<?php
declare (strict_types = 1);

namespace app\controller;

use app\model\Role;
use app\model\RolePermission;
use app\model\AdminRole;
use think\exception\ValidateException;
use think\facade\Db;

/**
 * 角色控制器
 * Class RoleController
 * @package app\controller
 */
class RoleController extends BaseController
{
    /**
     * 角色列表
     * @return \think\response\Json
     */
    public function index()
    {
        try {
            $page = $this->request->param('page', 1);
            $limit = $this->request->param('limit', 10);
            $keyword = $this->request->param('keyword', '');
            $status = $this->request->param('status', '');

            $where = [];
            if (!empty($keyword)) {
                $where[] = ['name|code', 'like', '%' . $keyword . '%'];
            }
            if ($status !== '') {
                $where[] = ['status', '=', $status];
            }

            $list = Role::with(['permissions'])
                ->where($where)
                ->order('sort', 'asc')
                ->order('id', 'asc')
                ->paginate([
                    'list_rows' => $limit,
                    'page' => $page
                ]);

            return $this->paginate($list);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取所有角色（不分页）
     * @return \think\response\Json
     */
    public function all()
    {
        try {
            // 记录开始查询
            \think\facade\Log::info('开始获取所有角色');

            // 构建查询
            $query = Role::where('status', 1)
                ->order('sort', 'asc')
                ->order('id', 'asc');

            // 记录查询条件
            \think\facade\Log::info('角色查询条件：' . $query->getLastSql());

            // 执行查询
            $roles = $query->select();

            // 记录查询结果
            \think\facade\Log::info('角色查询结果数量：' . count($roles));
            if (count($roles) === 0) {
                \think\facade\Log::warning('未找到任何启用状态的角色');
            } else {
                foreach ($roles as $role) {
                    \think\facade\Log::info('角色信息：', [
                        'id' => $role->id,
                        'name' => $role->name,
                        'code' => $role->code,
                        'status' => $role->status
                    ]);
                }
            }

            // 检查是否有超级管理员角色
            $hasSuperAdmin = false;
            foreach ($roles as $role) {
                if ($role->id === 1) {
                    $hasSuperAdmin = true;
                    break;
                }
            }
            if (!$hasSuperAdmin) {
                \think\facade\Log::warning('超级管理员角色（ID=1）未找到或未启用');
            }

            // 转换为数组并确保所有必要字段都存在
            $rolesArray = $roles->map(function ($role) {
                return [
                    'id' => $role->id,
                    'name' => $role->name,
                    'code' => $role->code,
                    'description' => $role->description,
                    'status' => $role->status,
                    'sort' => $role->sort
                ];
            })->toArray();

            \think\facade\Log::info('角色数据处理完成，准备返回');
            return $this->success($rolesArray);
        } catch (\Exception $e) {
            \think\facade\Log::error('获取角色列表失败：' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }

    /**
     * 角色详情
     * @param int $id
     * @return \think\response\Json
     */
    public function read(int $id)
    {
        try {
            $role = Role::with(['permissions'])->find($id);
            if (!$role) {
                return $this->error('角色不存在');
            }

            // 获取权限ID数组
            $role->permission_ids = $role->getPermissionIds();

            return $this->success($role);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 创建角色
     * @return \think\response\Json
     */
    public function save()
    {
        try {
            $data = $this->request->post();
            
            // 验证数据
            $this->validate($data, [
                'name' => 'require|length:2,20',
                'code' => 'require|alphaNum|length:2,50|unique:roles',
                'description' => 'length:0,255',
                'status' => 'in:0,1',
                'sort' => 'integer',
                'permission_ids' => 'array'
            ], [
                'name.require' => '角色名称不能为空',
                'name.length' => '角色名称长度为2-20位',
                'code.require' => '角色代码不能为空',
                'code.alphaNum' => '角色代码只能是字母和数字',
                'code.length' => '角色代码长度为2-50位',
                'code.unique' => '角色代码已存在',
                'description.length' => '角色描述长度不能超过255位',
                'status.in' => '状态值不正确',
                'sort.integer' => '排序必须是整数',
                'permission_ids.array' => '权限ID必须是数组'
            ]);

            Db::startTrans();
            try {
                // 创建角色
                $role = Role::create([
                    'name' => $data['name'],
                    'code' => $data['code'],
                    'description' => $data['description'] ?? '',
                    'status' => $data['status'] ?? 1,
                    'sort' => $data['sort'] ?? 0
                ]);

                // 分配权限
                if (!empty($data['permission_ids'])) {
                    $role->assignPermissions($data['permission_ids']);
                }

                Db::commit();
                return $this->success($role, '创建成功');
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        } catch (ValidateException $e) {
            return $this->error($e->getError());
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 更新角色
     * @param int $id
     * @return \think\response\Json
     */
    public function update(int $id)
    {
        try {
            $role = Role::find($id);
            if (!$role) {
                return $this->error('角色不存在');
            }

            $data = $this->request->put();
            
            // 验证数据
            $this->validate($data, [
                'name' => 'require|length:2,20',
                'code' => 'require|alphaNum|length:2,50|unique:roles,code,' . $id,
                'description' => 'length:0,255',
                'status' => 'in:0,1',
                'sort' => 'integer',
                'permission_ids' => 'array'
            ], [
                'name.require' => '角色名称不能为空',
                'name.length' => '角色名称长度为2-20位',
                'code.require' => '角色代码不能为空',
                'code.alphaNum' => '角色代码只能是字母和数字',
                'code.length' => '角色代码长度为2-50位',
                'code.unique' => '角色代码已存在',
                'description.length' => '角色描述长度不能超过255位',
                'status.in' => '状态值不正确',
                'sort.integer' => '排序必须是整数',
                'permission_ids.array' => '权限ID必须是数组'
            ]);

            Db::startTrans();
            try {
                // 更新角色信息
                $role->save([
                    'name' => $data['name'],
                    'code' => $data['code'],
                    'description' => $data['description'] ?? '',
                    'status' => $data['status'] ?? 1,
                    'sort' => $data['sort'] ?? 0
                ]);

                // 更新权限
                if (isset($data['permission_ids'])) {
                    $role->assignPermissions($data['permission_ids']);
                }

                Db::commit();
                return $this->success($role, '更新成功');
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        } catch (ValidateException $e) {
            return $this->error($e->getError());
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 删除角色
     * @param int $id
     * @return \think\response\Json
     */
    public function delete(int $id)
    {
        try {
            if ($id == 1) {
                return $this->error('不能删除超级管理员角色');
            }

            $role = Role::find($id);
            if (!$role) {
                return $this->error('角色不存在');
            }

            // 检查是否有管理员使用该角色
            $adminCount = AdminRole::where('role_id', $id)->count();
            if ($adminCount > 0) {
                return $this->error('该角色下还有管理员，不能删除');
            }

            Db::startTrans();
            try {
                // 删除角色权限关联
                RolePermission::where('role_id', $id)->delete();
                // 删除角色
                $role->delete();

                Db::commit();
                return $this->success([], '删除成功');
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 批量删除角色
     * @return \think\response\Json
     */
    public function batchDelete()
    {
        try {
            $ids = $this->request->post('ids', []);
            if (empty($ids) || !is_array($ids)) {
                return $this->error('请选择要删除的角色');
            }

            // 不能删除超级管理员角色
            if (in_array(1, $ids)) {
                return $this->error('不能删除超级管理员角色');
            }

            // 检查是否有管理员使用这些角色
            $adminCount = AdminRole::whereIn('role_id', $ids)->count();
            if ($adminCount > 0) {
                return $this->error('选中的角色下还有管理员，不能删除');
            }

            Db::startTrans();
            try {
                // 删除角色权限关联
                RolePermission::whereIn('role_id', $ids)->delete();
                // 删除角色
                Role::whereIn('id', $ids)->delete();

                Db::commit();
                return $this->success([], '批量删除成功');
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 修改状态
     * @param int $id
     * @return \think\response\Json
     */
    public function changeStatus(int $id)
    {
        try {
            if ($id == 1) {
                return $this->error('不能修改超级管理员角色状态');
            }

            $role = Role::find($id);
            if (!$role) {
                return $this->error('角色不存在');
            }

            $status = $this->request->post('status');
            if (!in_array($status, [0, 1])) {
                return $this->error('状态值不正确');
            }

            $role->status = $status;
            $role->save();

            return $this->success([], '状态修改成功');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取角色权限
     * @param int $id
     * @return \think\response\Json
     */
    public function getPermissions(int $id)
    {
        try {
            $role = Role::with(['permissions'])->find($id);
            if (!$role) {
                return $this->error('角色不存在');
            }

            // 获取权限详细信息，包含id字段
            $permissions = $role->permissions->map(function($permission) {
                return [
                    'id' => $permission->id,
                    'name' => $permission->name,
                    'code' => $permission->code
                ];
            })->toArray();

            // 提取权限ID数组
            $permissionIds = $role->permissions->map(function($permission) {
                return $permission->id;
            })->toArray();

            return $this->success([
                'role' => $role,
                'permissions' => $permissions,
                'permission_ids' => $permissionIds
            ]);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 更新角色权限
     * @param int $id
     * @return \think\response\Json
     */
    public function updatePermissions(int $id)
    {
        try {
            $role = Role::find($id);
            if (!$role) {
                return $this->error('角色不存在');
            }

            $data = $this->request->param();
            
            // 处理前端发送的数据格式，支持 permissions 或 permission_ids 字段
            $permissionIds = [];
            if (isset($data['permissions']) && is_array($data['permissions'])) {
                $permissionIds = $data['permissions'];
            } elseif (isset($data['permission_ids']) && is_array($data['permission_ids'])) {
                $permissionIds = $data['permission_ids'];
            } else {
                return $this->error('权限ID必须是数组');
            }

            // 分配权限
            $role->assignPermissions($permissionIds);

            return $this->success([], '权限分配成功');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }
}